package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.ServiceItemMapper;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IProcessService;
import com.ruoyi.business.service.IServiceItemService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 养修服务项Service业务层处理
 *
 * @author wolfcode
 * @date 2021-05-14
 */
@Service
public class ServiceItemServiceImpl implements IServiceItemService {
	@Autowired
	private ServiceItemMapper serviceItemMapper;
	@Autowired
	private ICarPackageAuditService carPackageAuditService;
	@Autowired
	private IProcessService processService;
	@Autowired
	private IDefinitionNodeService definitionNodeService;


	/**
	 * 查询养修服务项
	 *
	 * @param id 养修服务项ID
	 * @return 养修服务项
	 */
	@Override
	public ServiceItem selectServiceItemById(Long id) {
		return serviceItemMapper.selectServiceItemById(id);
	}

	/**
	 * 查询养修服务项列表
	 *
	 * @param serviceItem 养修服务项
	 * @return 养修服务项
	 */
	@Override
	public List<ServiceItem> selectServiceItemList(ServiceItem serviceItem) {
		return serviceItemMapper.selectServiceItemList(serviceItem);
	}

	/**
	 * 新增养修服务项
	 *
	 * @param serviceItem 养修服务项
	 * @return 结果
	 */
	@Override
	public int insertServiceItem(ServiceItem serviceItem) {
		serviceItem.setCreateTime(DateUtils.getNowDate());
		if (ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())) {
			serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);//设置初始化
		}
		return serviceItemMapper.insertServiceItem(serviceItem);
	}

	/**
	 * 修改养修服务项
	 *
	 * @param serviceItem 养修服务项
	 * @return 结果
	 */
	@Override
	@Transactional
	public int updateServiceItem(ServiceItem serviceItem) {
		ServiceItem oldObj = selectServiceItemById(serviceItem.getId());
		//处于上架状态的商品不能修改
		if (ServiceItem.SALESTATUS_ON.equals(oldObj.getSaleStatus())) {
			throw new BusinessException("上架服务项目不能修改，请下架后再修改");
		} else if (ServiceItem.AUDITSTATUS_AUDITING.equals(oldObj.getAuditStatus())) {
			throw new BusinessException("服务项目正在审核中,不可修改");
		}
		//如果是审核通过，此时修改，需要将其状态变更为初始化
		if (ServiceItem.AUDITSTATUS_APPROVED.equals(oldObj.getAuditStatus())) {
			serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
		}
		serviceItem.setVersion(oldObj.getVersion());
		return serviceItemMapper.updateServiceItem(serviceItem);
	}

	/**
	 * 删除养修服务项对象
	 *
	 * @param ids 需要删除的数据ID
	 * @return 结果
	 */
	@Override
	public int deleteServiceItemByIds(String ids) {
		return serviceItemMapper.deleteServiceItemByIds(Convert.toStrArray(ids));
	}

	/**
	 * 下架
	 *
	 * @param id 需要下架的服务项ID
	 * @return
	 */
	@Override
	public int saleOff(Long id) {
		return serviceItemMapper.changeSaleStatus(id, ServiceItem.SALESTATUS_OFF);
	}

	/**
	 * 上架
	 *
	 * @param id 需要上架的服务ID
	 * @return
	 */
	@Override
	public int saleOn(Long id) {
		ServiceItem serviceItem = selectServiceItemById(id);
		//如果不是套餐，可以直接上架
		//如果是套餐，只有审核成功才能上架
		if (ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())
				&& !ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())) {
			throw new BusinessException("套餐服务项需要审核通过之后才能上架");
		}
		return serviceItemMapper.changeSaleStatus(id, ServiceItem.SALESTATUS_ON);
	}

	@Override
	public int updateServiceItemById(Long itemId, Integer auditStatus) {
		return serviceItemMapper.updateServiceItemStatusById(itemId,auditStatus);
	}

	/**
	 * 发起套餐审核
	 *
	 * @param itemId
	 * @return
	 */
	@Override
	@Transactional
	public int startAudit(Long itemId) {
		//1.根据传入id查询服务项,服务项状态处于初始化才可能进行审核逻辑
		ServiceItem serviceItem = serviceItemMapper.selectServiceItemById(itemId);
		if (!ServiceItem.AUDITSTATUS_INIT.equals(serviceItem.getAuditStatus())) {
			throw new BusinessException("套餐状态为初始化才可审核！");
		}
		//2.修改服务项的状态,修改成审核中.
		serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_AUDITING);
		serviceItemMapper.updateServiceItem(serviceItem);
		//3.封装CarPackageAudit对象,把服务项转成JSON字符串,保存对象
		CarPackageAudit audit = new CarPackageAudit();
		audit.setServiceItemInfo(JSON.toJSONString(serviceItem));
		audit.setServiceItem(serviceItem);
		audit.setCreateBy(ShiroUtils.getUserId().toString());//当前登录用户id
		carPackageAuditService.insertCarPackageAudit(audit);
		//4.启动流程实例(CarPackageAudit的id作为业务key传入进去,把金额作为流程变量传进去),获得流程实例对象.
		String businessKey = String.valueOf(audit.getId());
		Map<String, Object> variables = new HashMap<>();
		variables.put("money", serviceItem.getDiscountPrice().longValue());
		ProcessInstance processInstance = processService.startProcessInstance(CarPackageAudit.DEFINITION_KEY, businessKey, variables);
		//5. 获取到当前流程中正在执行的节点,根据节点的 id 从数据表中查询对应的审核人.
		Task currentTask = processService.getExecutingTask(processInstance.getId());
		String nodeKey = currentTask.getTaskDefinitionKey();
		List<SysUser> auditors = definitionNodeService.selectAuditorsByNodeKey(nodeKey);
		List<String> auditorNames = new ArrayList<>();
		//6. 给当前任务去设置候选人 ====> 候选人的名字存储起来
		for (SysUser auditor : auditors) {
			//给任务添加对应的审核人
			processService.addCandidateUser(currentTask.getId(), auditor.getUserId());
			//把审核候选人的名称存起来
			auditorNames.add(auditor.getUserName());
		}
		//7.需要获取到流程实例ID,设置到CarPackageAudit对象
		audit.setInstanceId(processInstance.getProcessInstanceId());
		//8.获取到审核人的信息,设置CarPackageAudit对象的auditors属性中
		audit.setAuditors(JSON.toJSONString(auditorNames));
		//9.更新CarPackageAudit对象
		carPackageAuditService.updateCarPackageAudit(audit);
		return 1;
	}

	/**
	 * 查询上家的养修服务项列表
	 *
	 * @param serviceItem 养修服务项
	 * @return 养修服务项集合
	 */
	@Override
	public List<ServiceItem> selectAllSaleOnList(ServiceItem serviceItem) {
		return serviceItemMapper.selectAllSaleOnList(serviceItem);
	}
}
